//************************************************************************
//Developed by Guo Ming Li 2009/2010
//Source code:
//  The source code may be freely modified or used but this credit section may not be removed 
//  The original author must be notified of any modifications plus a copy of 
//  the changed source code
//Contact info: mailto://gming.li@gmail.com
//************************************************************************
using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using Microsoft.BizTalk.Operations;
using Microsoft.BizTalk.PipelineOM;
using Microsoft.BizTalk.Message.Interop;
using System.IO;

namespace GML.BizTalk.OperationManager.Library
{
    public class BTSMessage
    {
        public enum FilterOperator
        {
            IsGreaterThan,
            IsLessThan,
            Equal,
            IsNull,
            Exists,
        }

        public enum FilterParameters
        {
            MessageID,
            OriginatorPartyID,
            AdapterName,
            ServiceType,
            ServiceClass,
            ServiceInstanceID,
            ContextName,
            ContextNamespace,
            ContextValue,
            ContextObject,
            MessageType,
            CreationDate,
            CreationDateTime,
            HostName,
            OriginatorPartyName,
            MessageBox_DBName,
            MessageBox_DBServer,
            Url,
            MessageContent
        }

        public static List<BizTalkMessage> GetBizTalkMessages(string btsDbServerName, string btsMgntDbName, Dictionary<FilterParameters, object> filterParams)
        {

            BizTalkOperations btsOps = new BizTalkOperations(btsDbServerName, btsMgntDbName);
            //List<BizTalkMessage> biztalkMsg = new List<BizTalkMessage>();
            List<BizTalkMessage> resultListOfBiztalkMsg = new List<BizTalkMessage>();
            IEnumerator ieBtsMsg = btsOps.GetMessages().GetEnumerator();
            int iFilterCount = filterParams.Count;
            int iMatchCount = 0;
            BizTalkMessage msg = null;
            IEnumerator ieFilterParams = filterParams.Keys.GetEnumerator();
            try
            {
                while (ieBtsMsg.MoveNext())
                {
                    msg = (BizTalkMessage)ieBtsMsg.Current;
                    while (ieFilterParams.MoveNext())
                    {
                        FilterParameters filterKey = (FilterParameters)ieFilterParams.Current;
                        if (filterKey.Equals(FilterParameters.MessageType))
                        {
                            if (msg.MessageType != null && msg.MessageType.Equals(filterParams[filterKey].ToString()))
                            {
                                iMatchCount++;
                            }
                            else
                            {
                                break; //if not match, skip the rest of the filter
                            }
                        }
                        else if (filterKey.Equals(FilterParameters.CreationDate))
                        {
                            DateTime msgDate = msg.CreationTime;
                            DateTime filterDate = (DateTime)filterParams[filterKey];

                            if (msgDate != null
                                && msgDate.Date.Equals(filterDate.Date)
                                && msgDate.Month.Equals(filterDate.Month)
                                && msgDate.Year.Equals(filterDate.Year))
                            {
                                iMatchCount++;
                            }
                            else
                            {
                                break; //if not match, skip the rest of the filter
                            }
                        }
                        else if (filterKey.Equals(FilterParameters.CreationDateTime))
                        {
                            DateTime msgDate = msg.CreationTime;
                            DateTime filterDate = (DateTime)filterParams[filterKey];

                            if (msgDate != null
                                && msgDate.Date.Equals(filterDate.Date)
                                && msgDate.Month.Equals(filterDate.Month)
                                && msgDate.Year.Equals(filterDate.Year)
                                && msgDate.Hour.Equals(filterDate.Hour)
                                && msgDate.Minute.Equals(filterDate.Minute))
                            {
                                iMatchCount++;
                            }
                            else
                            {
                                break; //if not match, skip the rest of the filter
                            }
                        }
                        else if (filterKey.Equals(FilterParameters.HostName))
                        {
                            if (msg.HostName != null && msg.HostName.Equals(filterParams[filterKey].ToString()))
                            {
                                iMatchCount++;
                            }
                            else
                            {
                                break; //if not match, skip the rest of the filter
                            }
                        }
                        else if (filterKey.Equals(FilterParameters.OriginatorPartyName))
                        {
                            if (msg.OriginatorPartyName != null && msg.OriginatorPartyName.Equals(filterParams[filterKey].ToString()))
                            {
                                iMatchCount++;
                            }
                            else
                            {
                                break; //if not match, skip the rest of the filter
                            }
                        }
                        else if (filterKey.Equals(FilterParameters.MessageBox_DBName))
                        {
                            if (msg.MessageBox != null && msg.MessageBox.DBName != null && msg.MessageBox.DBName.Equals(filterParams[filterKey].ToString()))
                            {
                                iMatchCount++;
                            }
                            else
                            {
                                break; //if not match, skip the rest of the filter
                            }
                        }
                        else if (filterKey.Equals(FilterParameters.MessageBox_DBServer))
                        {
                            if (msg.MessageBox != null && msg.MessageBox.DBServer != null && msg.MessageBox.DBServer.Equals(filterParams[filterKey].ToString()))
                            {
                                iMatchCount++;
                            }
                            else
                            {
                                break; //if not match, skip the rest of the filter
                            }
                        }
                        else if (filterKey.Equals(FilterParameters.Url))
                        {
                            if (msg.Url != null && msg.Url.Equals(filterParams[filterKey].ToString()))
                            {
                                iMatchCount++;
                            }
                            else
                            {
                                break; //if not match, skip the rest of the filter
                            }
                        }
                        else if (filterKey.Equals(FilterParameters.AdapterName))
                        {
                            if (msg.AdapterName != null && msg.AdapterName.Equals(filterParams[filterKey].ToString()))
                            {
                                iMatchCount++;
                            }
                            else
                            {
                                break; //if not match, skip the rest of the filter
                            }
                        }
                        else if (filterKey.Equals(FilterParameters.MessageID))
                        {
                            if (msg.MessageID != null && msg.MessageID.Equals(filterParams[filterKey]))
                            {
                                iMatchCount++;
                            }
                            else
                            {
                                break; //if not match, skip the rest of the filter
                            }
                        }
                        else if (filterKey.Equals(FilterParameters.ServiceClass))
                        {
                            if (msg.Class.ToString().Equals(filterParams[filterKey].ToString()))
                            {
                                iMatchCount++;
                            }
                            else
                            {
                                break; //if not match, skip the rest of the filter
                            }
                        }
                        else if (filterKey.Equals(FilterParameters.ServiceType))
                        {
                            if (msg.ServiceType != null && msg.ServiceType.Equals(filterParams[filterKey].ToString()))
                            {
                                iMatchCount++;
                            }
                            else
                            {
                                break; //if not match, skip the rest of the filter
                            }
                        }
                        else if (filterKey.Equals(FilterParameters.MessageContent))
                        {
                            bool isMatch = false;
                            for (int i = 0; i < msg.PartCount; i++)
                            {
                                string sPartName = null;
                                IBaseMessagePart ibMsgPart = msg.GetPartByIndex(i, out sPartName);
                                string contents = null;
                                using (StreamReader reader = new StreamReader(ibMsgPart.GetOriginalDataStream()))
                                {
                                    contents = reader.ReadToEnd();
                                }
                                if (contents != null && contents.Contains(filterParams[filterKey].ToString()))
                                {
                                    isMatch = true;
                                    break; //if match, skip the rest of the parts
                                }
                                ibMsgPart = null;
                                sPartName = null;
                                contents = null;
                            }
                            if (isMatch)
                            {
                                iMatchCount++;
                            }
                            else
                            {
                                break; //if not match, skip the rest of the filter
                            }
                        }

                    }
                    ieFilterParams.Reset();
                    if (iMatchCount == iFilterCount)
                    {
                        resultListOfBiztalkMsg.Add(msg);
                    }
                    iMatchCount = 0;

                }

                return resultListOfBiztalkMsg;
            }
            catch (Exception ex)
            {

                throw ex;
            }
            finally
            {
                btsOps = null;
                resultListOfBiztalkMsg = null;
                ieBtsMsg = null;
                ieFilterParams = null;
                msg = null;
            }

        }

        public static void PrintMessages(List<BizTalkMessage> biztalkMsgs)
        {
            string strName = null;
            string strNamespace = null;
            object obj = null;
            try
            {
                foreach (BizTalkMessage btsMsg in biztalkMsgs)
                {
                    System.Diagnostics.Debug.WriteLine("-----------------------------------------------------");
                    debug("btsMsg.AdapterName", btsMsg.AdapterName);
                    debug("btsMsg.BodyPart", btsMsg.BodyPart);
                    debug("btsMsg.BodyPartName", btsMsg.BodyPartName);
                    for (int i = 0; i < btsMsg.Context.CountProperties; i++)
                    {
                        strName = null;
                        strNamespace = null;
                        obj = btsMsg.Context.ReadAt(i, out strName, out strNamespace);
                        debug("---->btsMsg..Context[" + strNamespace + "#" + strName + "] = ", obj);
                    }
                    debug("btsMsg.Class", btsMsg.Class);
                    debug("btsMsg.CreationTime", btsMsg.CreationTime);
                    debug("btsMsg.ErrorCode", btsMsg.ErrorCode);
                    debug("btsMsg.ErrorDescription", btsMsg.ErrorDescription);
                    debug("btsMsg.HostName", btsMsg.HostName);
                    debug("btsMsg.InstanceID", btsMsg.InstanceID);
                    debug("btsMsg.InstanceStatus", btsMsg.InstanceStatus);
                    debug("btsMsg.MessageBox_DBName", btsMsg.MessageBox.DBName);
                    debug("btsMsg.MessageID", btsMsg.MessageID);
                    debug("btsMsg.MessageStatus", btsMsg.MessageStatus);
                    debug("btsMsg.MessageType", btsMsg.MessageType);
                    debug("btsMsg.OriginatorPartyName", btsMsg.OriginatorPartyName);
                    debug("btsMsg.OriginatorSecurityName", btsMsg.OriginatorSecurityName);
                    debug("btsMsg.PartCount", btsMsg.PartCount);
                    for (int i = 0; i < btsMsg.PartCount; i++)
                    {
                        string sPartName = null;
                        IBaseMessagePart ibMsgPart = btsMsg.GetPartByIndex(i, out sPartName);
                        string contents = null;
                        using (StreamReader reader = new StreamReader(ibMsgPart.GetOriginalDataStream()))
                        {
                            contents = reader.ReadToEnd();
                        }
                        debug("---->btsMsg.Part(" + i + ").PartName", sPartName);
                        debug("---->btsMsg.Part(" + i + ").Charset", ibMsgPart.Charset);
                        debug("---->btsMsg.Part(" + i + ").ContentType", ibMsgPart.ContentType);
                        debug("---->btsMsg.Part(" + i + ").GetOriginalDataStream()", ibMsgPart.GetOriginalDataStream());
                        debug("---->btsMsg.Part(" + i + ") Contents", contents);
                        debug("---->btsMsg.Part(" + i + ").IsMutable", ibMsgPart.IsMutable);
                        debug("---->btsMsg.Part(" + i + ").PartID", ibMsgPart.PartID);
                        debug("---->btsMsg.Part(" + i + ").PartProperties", ibMsgPart.PartProperties);
                        sPartName = null;
                        ibMsgPart = null;
                        contents = null;
                    }
                    debug("btsMsg.ReferenceID", btsMsg.ReferenceID);
                    debug("btsMsg.RetryCount", btsMsg.RetryCount);
                    debug("btsMsg.ServiceType", btsMsg.ServiceType);
                    debug("btsMsg.ServiceTypeID", btsMsg.ServiceTypeID);
                    debug("btsMsg.Submitter", btsMsg.Submitter);
                    debug("btsMsg.Url", btsMsg.Url);
                    System.Diagnostics.Debug.WriteLine("-----------------------------------------------------");
                }
            }
            catch (Exception ex)
            {

                throw ex;
            }
            finally
            {
                strName = null;
                strNamespace = null;
                obj = null;

            }
        }

        public static void GetMessages(string btsDbServerName, string btsMgntDbName, string sMessageType)
        {
            BizTalkOperations btsOps = new BizTalkOperations(btsDbServerName, btsMgntDbName);
            List<BizTalkMessage> biztalkMsg = new List<BizTalkMessage>();
            BizTalkMessage btsMsg = null;
            string strName = null;
            string strNamespace = null;
            object obj = null;
            IEnumerator ieBtsMsg = btsOps.GetMessages().GetEnumerator();
            try
            {
                while (ieBtsMsg.MoveNext())
                {
                    btsMsg = (BizTalkMessage)ieBtsMsg.Current;
                    if (btsMsg.MessageType != null && btsMsg.MessageType.Equals(sMessageType))
                    {
                        System.Diagnostics.Debug.WriteLine("-----------------------------------------------------");
                        debug("btsMsg.AdapterName", btsMsg.AdapterName);
                        debug("btsMsg.BodyPart", btsMsg.BodyPart);
                        debug("btsMsg.BodyPartName", btsMsg.BodyPartName);
                        debug("btsMsg.Class", btsMsg.Class);
                        for (int i = 0; i < btsMsg.Context.CountProperties; i++)
                        {
                            strName = null;
                            strNamespace = null;
                            obj = btsMsg.Context.ReadAt(i, out strName, out strNamespace);
                            debug("---->btsMsg..Context[" + strNamespace + "#" + strName + "] = ", obj);
                        }
                        debug("btsMsg.CreationTime", btsMsg.CreationTime);
                        debug("btsMsg.ErrorCode", btsMsg.ErrorCode);
                        debug("btsMsg.ErrorDescription", btsMsg.ErrorDescription);
                        debug("btsMsg.HostName", btsMsg.HostName);
                        debug("btsMsg.InstanceID", btsMsg.InstanceID);
                        debug("btsMsg.InstanceStatus", btsMsg.InstanceStatus);
                        debug("btsMsg.MessageBox_DBName", btsMsg.MessageBox.DBName);
                        debug("btsMsg.MessageID", btsMsg.MessageID);
                        debug("btsMsg.MessageStatus", btsMsg.MessageStatus);
                        debug("btsMsg.MessageType", btsMsg.MessageType);
                        debug("btsMsg.OriginatorPartyName", btsMsg.OriginatorPartyName);
                        debug("btsMsg.OriginatorSecurityName", btsMsg.OriginatorSecurityName);
                        debug("btsMsg.PartCount", btsMsg.PartCount);
                        for (int i = 0; i < btsMsg.PartCount; i++)
                        {
                            string sPartName = null;
                            IBaseMessagePart ibMsgPart = btsMsg.GetPartByIndex(i, out sPartName);
                            string contents = null;
                            using (StreamReader reader = new StreamReader(ibMsgPart.GetOriginalDataStream()))
                            {
                                contents = reader.ReadToEnd();
                            }
                            debug("---->btsMsg.Part(" + i + ").PartName", sPartName);
                            debug("---->btsMsg.Part(" + i + ").Charset", ibMsgPart.Charset);
                            debug("---->btsMsg.Part(" + i + ").ContentType", ibMsgPart.ContentType);
                            debug("---->btsMsg.Part(" + i + ").GetOriginalDataStream()", ibMsgPart.GetOriginalDataStream());
                            debug("---->btsMsg.Part(" + i + ") Contents", contents);
                            debug("---->btsMsg.Part(" + i + ").IsMutable", ibMsgPart.IsMutable);
                            debug("---->btsMsg.Part(" + i + ").PartID", ibMsgPart.PartID);
                            debug("---->btsMsg.Part(" + i + ").PartProperties", ibMsgPart.PartProperties);
                            sPartName = null;
                            ibMsgPart = null;
                            contents = null;
                        }
                        debug("btsMsg.ReferenceID", btsMsg.ReferenceID);
                        debug("btsMsg.RetryCount", btsMsg.RetryCount);
                        debug("btsMsg.ServiceType", btsMsg.ServiceType);
                        debug("btsMsg.ServiceTypeID", btsMsg.ServiceTypeID);
                        debug("btsMsg.Submitter", btsMsg.Submitter);
                        debug("btsMsg.Url", btsMsg.Url);
                        System.Diagnostics.Debug.WriteLine("-----------------------------------------------------");
                        biztalkMsg.Add(btsMsg);
                    }

                }
                System.Diagnostics.Debug.WriteLine("biztalkMsg.size = " + biztalkMsg.Count);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                btsOps = null;
                biztalkMsg = null;
                btsMsg = null;
                strName = null;
                strNamespace = null;
                obj = null;
                ieBtsMsg = null;
            }
        }
        public static void dosomething(string btsDbServerName, string btsMgntDbName)
        {
            BizTalkOperations btsOps = new BizTalkOperations(btsDbServerName, btsMgntDbName);
            BizTalkMessage btsMsg = null;
            IEnumerator ieBtsMsg = btsOps.GetMessages().GetEnumerator();
            try
            {
                while (ieBtsMsg.MoveNext())
                {
                    btsMsg = (BizTalkMessage)ieBtsMsg.Current;
                    System.Diagnostics.Debug.WriteLine("-----------------------------------------------------");
                    debug("btsMsg.AdapterName", btsMsg.AdapterName);
                    debug("btsMsg.BodyPart", btsMsg.BodyPart);
                    debug("btsMsg.BodyPartName", btsMsg.BodyPartName);
                    debug("btsMsg.Class", btsMsg.Class);
                    debug("btsMsg.CreationTime", btsMsg.CreationTime);
                    debug("btsMsg.ErrorCode", btsMsg.ErrorCode);
                    debug("btsMsg.ErrorDescription", btsMsg.ErrorDescription);
                    debug("btsMsg.HostName", btsMsg.HostName);
                    debug("btsMsg.InstanceID", btsMsg.InstanceID);
                    debug("btsMsg.InstanceStatus", btsMsg.InstanceStatus);
                    debug("btsMsg.MessageBox.DBName", btsMsg.MessageBox.DBName);
                    debug("btsMsg.MessageID", btsMsg.MessageID);
                    debug("btsMsg.MessageStatus", btsMsg.MessageStatus);
                    debug("btsMsg.MessageType", btsMsg.MessageType);
                    debug("btsMsg.OriginatorPartyName", btsMsg.OriginatorPartyName);
                    debug("btsMsg.OriginatorSecurityName", btsMsg.OriginatorSecurityName);
                    debug("btsMsg.PartCount", btsMsg.PartCount);
                    for (int i = 0; i < btsMsg.PartCount; i++)
                    {
                        string sPartName = null;
                        IBaseMessagePart ibMsgPart = btsMsg.GetPartByIndex(i, out sPartName);
                        string contents = null;
                        using (StreamReader reader = new StreamReader(ibMsgPart.GetOriginalDataStream()))
                        {
                            contents = reader.ReadToEnd();
                        }
                        debug("---->btsMsg.Part(" + i + ").PartName", sPartName);
                        debug("---->btsMsg.Part(" + i + ").Charset", ibMsgPart.Charset);
                        debug("---->btsMsg.Part(" + i + ").ContentType", ibMsgPart.ContentType);
                        debug("---->btsMsg.Part(" + i + ").GetOriginalDataStream()", ibMsgPart.GetOriginalDataStream());
                        debug("---->btsMsg.Part(" + i + ") Contents", contents);
                        debug("---->btsMsg.Part(" + i + ").IsMutable", ibMsgPart.IsMutable);
                        debug("---->btsMsg.Part(" + i + ").PartID", ibMsgPart.PartID);
                        debug("---->btsMsg.Part(" + i + ").PartProperties", ibMsgPart.PartProperties);
                        sPartName = null;
                        ibMsgPart = null;
                        contents = null;
                    }
                    debug("btsMsg.ReferenceID", btsMsg.ReferenceID);
                    debug("btsMsg.RetryCount", btsMsg.RetryCount);
                    debug("btsMsg.ServiceType", btsMsg.ServiceType);
                    debug("btsMsg.ServiceTypeID", btsMsg.ServiceTypeID);
                    debug("btsMsg.Submitter", btsMsg.Submitter);
                    debug("btsMsg.Url", btsMsg.Url);
                    System.Diagnostics.Debug.WriteLine("-----------------------------------------------------");


                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                btsOps = null;
                btsMsg = null;
                ieBtsMsg = null;
            }
        }

        public static void debug(string name, object obj)
        {
            if (obj != null)
            {
                System.Diagnostics.Debug.WriteLine(name + " = " + obj.ToString());
            }
            else
            {
                System.Diagnostics.Debug.WriteLine(name + " is null");
            }
        }
    }

}
